#include <stdbool.h>
#include <stdint.h>

#include "rt.h"

struct task_ctx
{
  uintptr_t size;
};

static bool
stop (struct runtime *rt, struct task_ctx *ctx)
{
  return false;
}

static bool
on_read_err (struct runtime *rt, struct task_ctx *ctx)
{
  rt_close (rt, (struct ev_close){ .fp = rt->fp, .then = stop });
  return false;
}

static bool
on_read_block_end (struct runtime *rt, struct task_ctx *ctx)
{
  ctx->size += rt->iolen;
  fprintf (stderr, "total bytes: %d\n", (int)ctx->size);

  rt_close (rt, (struct ev_close){ .fp = rt->fp, .then = stop });
  return true;
}

static bool
on_read_block (struct runtime *rt, struct task_ctx *ctx)
{
  ctx->size += rt->iolen;
  rt_read (rt, (struct ev_read){ .fp = rt->fp,
                                 .on_ok = on_read_block,
                                 .on_eof = on_read_block_end,
                                 .on_error = on_read_err });
  return true;
}

static bool
on_open (struct runtime *rt, struct task_ctx *ctx)
{
  rt_read (rt, (struct ev_read){ .fp = rt->fp,
                                 .on_ok = on_read_block,
                                 .on_eof = on_read_block_end,
                                 .on_error = on_read_err });
  return true;
}

static bool
start (struct runtime *rt, struct task_ctx *ctx)
{
  ctx->size = 0;
  rt_open (rt, (struct ev_open){ .path = "/usr/bin/gcc",
                                 .on_ok = on_open,
                                 .on_error = stop });
  return true;
}

int
main (void)
{
  struct task_ctx ctx;
  struct runtime rt = rt_make_runtime ();

  rt_run (&rt, start, &ctx);
  return 0;
}
